package cn;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA demo
 */
public class RSADemo {
    private static  String src= "infcn";
    private static RSAPublicKey rsaPublicKey=null;
    private static RSAPrivateKey rsaPrivateKey=null;
    static {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(512);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
            rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
            System.out.println("public key :" + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
            System.out.println("private key :" + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
        }catch (NoSuchAlgorithmException e){
            e.printStackTrace();
        }

    }

    /**
     * 公钥加密，私钥解密
     */
    private static void  pubEn2PriDe() throws Exception{
        X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        byte[] bytes = cipher.doFinal(src.getBytes());
        System.out.println("公钥加密，私钥解密 ---加密："+ Base64.encodeBase64String(bytes));

        PKCS8EncodedKeySpec pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
        keyFactory= KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        cipher=Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        bytes=cipher.doFinal(bytes);
        System.out.println("公钥加密，私钥解密 ---解密："+new String(bytes));
        System.out.println("公钥加密，私钥解密 ---解密："+Base64.encodeBase64String(bytes));
    }

    /**
     * 私钥加密，公钥解密
     */
    private static void priEn2PubDe() throws Exception{
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,privateKey);
        byte[] bytes = cipher.doFinal(src.getBytes());
        System.out.println("私钥加密，公钥解密---加密"+ Base64.encodeBase64String(bytes));

        X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());
        keyFactory=KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE,publicKey);
        bytes=cipher.doFinal(bytes);
        System.out.println("私钥加密，公钥解密---解密"+ new String(bytes));
    }


    public static void main(String[] args) throws Exception {
        pubEn2PriDe();
        priEn2PubDe();
    }
}
